#include "comm.h"

void Usage(char *proc)
{
    std::cout << "Usage:\n\t" << proc << " server.port" << std::endl;
}

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        Usage(argv[0]);
        return -1;
    }
    int sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock < 0)
    {
        std::cout << "socket failed" << std::endl;
        return 1;
    }

    struct sockaddr_in local;
    memset(&local, 0, sizeof(local));
    local.sin_family = AF_INET;
    local.sin_port = htons(atoi(argv[1]));
    local.sin_addr.s_addr = INADDR_ANY;

    if (bind(sock, (struct sockaddr *)&local, sizeof(local)) != 0)
    {
        std::cout << "bind failed" << std::endl;
        return 2;
    }

    std::cout << "bind success" << std::endl;

    const int back_log = 5;
    if (listen(sock, back_log) < 0)
    {
        std::cerr << "listen failed" << errno << std::endl;
        return 3;
    }
    std::cout << "listen success" << std::endl;

    signal(SIGCHLD, SIG_IGN);
    while (true)
    {
        struct sockaddr_in peer;
        socklen_t len = sizeof(peer);
        int new_sock = accept(sock, (struct sockaddr *)&peer, &len);
        std::string cli_ip = inet_ntoa(peer.sin_addr);
        uint16_t cli_port = ntohs(peer.sin_port);

        std::cout << "cat a new client[" << cli_ip << ":" << cli_port << "]" << std::endl;

        if (new_sock >= 0)
        {
            pid_t pid = fork();
            if (pid == 0)
            {
                std::cout << "I'm child process";
                if (fork() == 0)
                {
                    // 孙子进程
                    close(sock);
                    char from_client[1024] = {0};
                    // ssize_t size = recvfrom(new_sock, from_client, sizeof(from_client), 0, (struct sockaddr*)&peer, &len);
                    while (true)
                    {
                        ssize_t size = read(new_sock, from_client, sizeof(from_client) - 1);
                        if (size > 0)
                        {
                            from_client[size] = 0;
                            std::cout << "client say: " << from_client << std::endl;
                            FILE *fp = popen(from_client, "r");
                            char line[1024] = {0};
                            std::string echo_hello = from_client;
                            echo_hello += "\n";
                            while (fgets(line, sizeof(line) - 1, fp) != NULL)
                            {
                                echo_hello += line;
                            }
                            fclose(fp);
                            // sendto(new_sock, echo_hello.c_str(), echo_hello.size(), 0, (struct sockaddr*)&peer, len);
                            write(new_sock, echo_hello.c_str(), echo_hello.size());
                        }
                        else if (size <= 0)
                        {
                            break;
                        }
                    }
                }
                //子进程
                close(new_sock);
                exit(0);
            }
            // 父进程
            waitpid(pid, nullptr, 0);
            close(new_sock);
        }
        else
        {
            std::cout << "accept failed" << std::endl;
            continue;
        }
    }
}